package com.gdkj.tencent;

import com.alibaba.fastjson.JSONObject;
import com.gdkj.util.TLSSigAPIv2;
import com.gdkj.util.Utils;
import com.tencentcloudapi.ame.v20190916.AmeClient;
import com.tencentcloudapi.ame.v20190916.models.*;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.xjgks.common.exception.handler.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * 音乐机器人
 */
@Service
@Slf4j
public class ImMusicRobotService implements IImMusicRobot {

    @Value("${TCIM_SDK_APPID}")
    private String imAppId;

    @Value("${TCIM_SDK_KEY}")
    private String imAppKey;

    /**
     * 创建直播互动机器人
     * @param liveUid 房主uid
     * @param userId 用户uid
     * @param syncRobotCommands 机器人自定义指令
     * @return LogicResult
     */
    @Override
    public CreateKTVRobotResponse createRobot(String liveUid, String userId, SyncRobotCommand[] syncRobotCommands) {
        CreateKTVRobotResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CreateKTVRobotRequest req = new CreateKTVRobotRequest();
            TRTCJoinRoomInput TRTCJoinRoomInput = new TRTCJoinRoomInput();

            TLSSigAPIv2 api = new TLSSigAPIv2(Long.parseLong(imAppId), imAppKey);
            //生成用户签名
            String userSig = api.genUserSig(userId, 180 * 86400);

            TRTCJoinRoomInput.setSign(userSig);
            TRTCJoinRoomInput.setRoomId(liveUid);
            TRTCJoinRoomInput.setSdkAppId(imAppId);
            TRTCJoinRoomInput.setUserId(userId);

            JoinRoomInput JoinRoomInput = new JoinRoomInput();
            JoinRoomInput.setTRTCJoinRoomInput(TRTCJoinRoomInput);
            req.setRTCSystem("TRTC");
            req.setJoinRoomInput(JoinRoomInput);
            if (syncRobotCommands != null) {
                req.setSyncRobotCommands(syncRobotCommands);
            }
            // 返回的resp是一个CreateKTVRobotResponse的实例，与请求对象对应
            resp = client.CreateKTVRobot(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        log.info("创建机器人日志: " + JSONObject.toJSONString(resp));
        return resp;
    }

    /**
     * 机器人添加歌曲
     * @param robotId 机器人id
     * @param musicIds 音乐id集合
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse addMusic(String robotId, String[] musicIds) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlaylistCommandInput SetPlaylistCommandInput = new SetPlaylistCommandInput();
            SetPlaylistCommandInput.setType("Add");
            SetPlaylistCommandInput.setIndex((long) -1);
            SetPlaylistCommandInput.setMusicIds(musicIds);

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlaylist");
            req.setSetPlaylistCommandInput(SetPlaylistCommandInput);

            resp = client.SyncKTVRobotCommand(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人播放音乐
     * @param robotId 机器人id
     * @param index 播放位置 (起始位为0)
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse playMusic(String robotId, Integer index) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            PlayCommandInput PlayCommandInput = new PlayCommandInput();
            PlayCommandInput.setIndex(0L);

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("Play");
            req.setPlayCommandInput(PlayCommandInput);

            resp = client.SyncKTVRobotCommand(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人暂停音乐
     * @param robotId 机器人id
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse stopMusic(String robotId) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("Pause");

            resp = client.SyncKTVRobotCommand(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人播放下一首
     * @param robotId 机器人id
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse nextMusic(String robotId) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SwitchNext");

            resp = client.SyncKTVRobotCommand(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人删除歌曲
     * @param robotId 机器人id
     * @param index 播放位置 (起始位为0)
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse deleteMusic(String robotId, Integer index) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlaylistCommandInput SetPlaylistCommandInput = new SetPlaylistCommandInput();
            SetPlaylistCommandInput.setType("Delete");
            SetPlaylistCommandInput.setIndex(Long.valueOf(index));

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlaylist");
            req.setSetPlaylistCommandInput(SetPlaylistCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人清空歌曲列表
     * @param robotId 机器人id
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse clearMusic(String robotId) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlaylistCommandInput SetPlaylistCommandInput = new SetPlaylistCommandInput();
            SetPlaylistCommandInput.setType("ClearList");

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlaylist");
            req.setSetPlaylistCommandInput(SetPlaylistCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人移动歌曲
     * @param robotId 机器人id
     * @param index 待调整歌曲的位置 (起始位为0)
     * @param changedIndex 表示移动歌曲的目标位置
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse moveMusic(String robotId, Integer index, Integer changedIndex) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlaylistCommandInput SetPlaylistCommandInput = new SetPlaylistCommandInput();
            SetPlaylistCommandInput.setType("Move");
            SetPlaylistCommandInput.setIndex(Long.valueOf(index));
            SetPlaylistCommandInput.setChangedIndex(Long.valueOf(changedIndex));

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlaylist");
            req.setSetPlaylistCommandInput(SetPlaylistCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人设置播放模式
     * @param robotId 机器人id
     * @param playMode 播放模式 RepeatPlaylist：列表循环；Order：顺序播放；RepeatSingle：单曲循环；Shuffle：随机播放
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse setPlayMode(String robotId, String playMode) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlayModeCommandInput SetPlayModeCommandInput = new SetPlayModeCommandInput();
            SetPlayModeCommandInput.setPlayMode(playMode);

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlayMode");
            req.setSetPlayModeCommandInput(SetPlayModeCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人设置音量
     * @param robotId 机器人id
     * @param volume 音量 0~100，默认值为 50
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse setVolume(String robotId, Integer volume) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetVolumeCommandInput SetVolumeCommandInput = new SetVolumeCommandInput();
            SetVolumeCommandInput.setVolume(Long.valueOf(volume));

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetVolume");
            req.setSetVolumeCommandInput(SetVolumeCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 机器人音频参数信息
     * @param robotId 机器人id
     * @param definition 规格 audio/mi：低规格；audio/lo：中规格；audio/hi：高规格
     * @param type 音频类型 Original：原唱；Accompaniment：伴奏
     * @return SyncKTVRobotCommandResponse
     */
    @Override
    public SyncKTVRobotCommandResponse setAudioParam(String robotId, String definition, String type) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetAudioParamCommandInput SetAudioParamCommandInput = new SetAudioParamCommandInput();
            SetAudioParamCommandInput.setDefinition(definition);
            SetAudioParamCommandInput.setType(type);

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetAudioParam");
            req.setSetAudioParamCommandInput(SetAudioParamCommandInput);

            resp = client.SyncKTVRobotCommand(req);

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }

    /**
     * 获取机器人信息，以及播放列表
     * @param robotIds 机器人集合
     * @param statuses 状态 Play：播放； Pause：暂停；Destroy：销毁
     * @return DescribeKTVRobotsResponse
     */
    @Override
    public DescribeKTVRobotsResponse getRobotPlayList(String[] robotIds, String[] statuses) {
        DescribeKTVRobotsResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeKTVRobotsRequest req = new DescribeKTVRobotsRequest();
            if (robotIds != null) {
                req.setRobotIds(robotIds);
            }
            if (statuses != null) {
                req.setStatuses(statuses);
            }

            resp = client.DescribeKTVRobots(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        log.info("获取机器人信息日志: " + JSONObject.toJSONString(resp));
        return resp;
    }

    /**
     * 销毁机器人
     * @param robotId 机器人id
     * @return DestroyKTVRobotResponse
     */
    @Override
    public DestroyKTVRobotResponse destroyRobot(String robotId) {
        DestroyKTVRobotResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DestroyKTVRobotRequest req = new DestroyKTVRobotRequest();
            req.setRobotId(robotId);

            resp = client.DestroyKTVRobot(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        log.info("销毁机器人日志: " + JSONObject.toJSONString(resp));
        return resp;
    }

    /**
     * 机器人发送指令
     */
    private SyncKTVRobotCommandResponse robotSendCommand(String robotId) {
        SyncKTVRobotCommandResponse resp = null;
        try {
            AmeClient client = Utils.getAmeClient();

            SetPlaylistCommandInput SetPlaylistCommandInput = new SetPlaylistCommandInput();
            SetPlaylistCommandInput.setType("Add");
            SetPlaylistCommandInput.setIndex((long) -1);

            SyncKTVRobotCommandRequest req = new SyncKTVRobotCommandRequest();
            req.setRobotId(robotId);
            req.setCommand("SetPlaylist");
            req.setSetPlaylistCommandInput(SetPlaylistCommandInput);

            resp = client.SyncKTVRobotCommand(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new RRException(e.toString());
        }
        return resp;
    }
}
